package tedu.week03.often_class;

/**
 * <pre>
 *  java.lang.Object类.
 *      Object类是所有类的父类.
 *          共有11个方法.其中在JDK9里面废弃一个finalize().所以要学习的是10个方法.有5个在学习线程时再学习.只需要学习5个即可.
 *      构造器:
 *          public Object (){}
 *      方法:
 *------------------------------------------------------------------------------
 *          public boolean equals(Object obj)           比较两个对象是否相等
 *------------------------------------------------------------------------------
 *         public final Class getClass()            返回当前对象的class类.
 *         可以放到反射的时候再讲.
 *------------------------------------------------------------------------------
 *         public int hashCode()                        返回当前对象的hash码值.
 *------------------------------------------------------------------------------
 *         public String toString()                     返回当前对象的字符串表述形式
 *------------------------------------------------------------------------------
 *          protected Object clone()                    创建并返回此对象的一个副本。
 *              throws CloneNotSupportedException               抛出 不支持克隆异常(没实现Cloneable接口)
 *              一般情况下,是分为浅拷备及深拷备.
 *              浅拷备就是:clone()在属性有引用对象时.两个实例的引用对象指向同一个引用对象.
 *              实现深拷备:如果想实现引用对象实例也克隆的话,那么就需要将引用类也实现克隆.
 *------------------------------------------------------------------------------
 *          protected void finalize()                   由垃圾回收器确定当前对象不再有调用时,让当前对象调用此方法.
 *                   throws Throwable                   虚拟机只调用一次当前方法.
 *------------------------------------------------------------------------------
 *         public final void notify()                   唤醒当前对象监视的单个线程,如果有多个唤醒随机一个.
 *------------------------------------------------------------------------------
 *         public final void notifyAll()                唤醒当前对象监视的所有线程.
 *------------------------------------------------------------------------------
 *         public final void wait()                     本对象唤醒其它线程时,当前线程等待
 *         throws InterruptedException
 *         public final void wait(long timeout)         本对象唤醒其它线程时,或者超出指定的时间量,当前线程等待
 *         throws InterruptedException
 *         public final void wait(long timeout,int nanos)本对象唤醒其它线程时,本线程中断或超出指定时间量,当前线程等待.
 *         throws InterruptedException
 *------------------------------------------------------------------------------
 * </pre>
 *
 * @author : resty
 * @date : 2019年06月01日    09时
 **/
public class Week03_Object {
    public static void main(String[] args) {
        Person per = new Person("王五", new Address("cba"));
        Person per1 = null;
        try {
            per1 = (Person) per.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        System.out.println(per.name + "===========" + per1.name);
        System.out.println(per.address.province);//cba
        System.out.println(per1.address.province);//cba
        /**clone()在属性有引用对象时.两个实例的引用对象指向同一个引用对象.*/
        per1.address.province = "abc";
        System.out.println(per.address.province);//abc
        System.out.println(per1.address.province);//abc
        /**
         * 如果想实现引用对象实例也克隆的话,那么就需要将引用类也实现克隆.
         */


    }
}

/**clone的测试**/
class Person implements Cloneable {
    String name = "张三";
    Address address;
    public Person() { }

    public Person(String name) { this.name = name;   }

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

//    @Override
//    protected Object clone() throws CloneNotSupportedException {
//        return super.clone();
//    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person per = (Person) super.clone();
        per.address = (Address) per.address.clone();
        return per;
    }
}

class Address implements Cloneable {
    String province = "abc";

    public Address(String province) {
        this.province = province;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}